/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.click.app.webapp.action;

import com.click.app.model.AsignationPantPay;
import com.click.app.model.BalanceEmployee;
import com.click.app.model.Employee;
import com.click.app.model.PaymentsPant;
import com.click.app.model.PeriodPaymentEmployee;
import com.click.app.model.ProcessDressmaker;
import com.click.app.service.AsignationPantPayManager;
import com.click.app.service.BalanceEmployeeManager;
import com.click.app.service.EmployeeManager;
import com.click.app.service.PaymentsPantManager;
import com.click.app.service.PeriodPaymentEmployeeManager;
import com.click.app.service.ProcessDressmakerManager;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author ariel
 */
public class PaymentsPantAction extends BaseAction {

    private PaymentsPantManager paymentsPantManager;
    private AsignationPantPayManager asignationPantPayManager;
    private EmployeeManager employeeManager;
    private ProcessDressmakerManager processDressmakerManager;
    private BalanceEmployeeManager balanceEmployeeManager;
    private List<PaymentsPant> paymentsPants;
    private List<BalanceEmployee> balances;
    private PaymentsPant paymentsPant;
    private Long id;
    private Employee employee;
    private Long idEmployee;
    private boolean editable;
    private Long lastBalanceId;
    private boolean canAdd;
    private List<ProcessDressmaker> processDressmakers;
    private Double availableAmount;

    private PeriodPaymentEmployee periodPaymentEmployee;
    private PeriodPaymentEmployeeManager periodPaymentEmployeeManager;
    private String observation;

    public Double getAvailableAmount() {
        employee = (Employee) getSession().getAttribute("employee");
        periodPaymentEmployee = periodPaymentEmployeeManager.getCurrentPeriodByIdEmployeeAndRole(employee.getId(), employee.getRoleByName("ROLE_EMPLOYEE_DRESSMAKER").getIdRole());
        
        return periodPaymentEmployee.getCurrentAmount();
    }

    public String generateProcessDressmakerList() {
        System.out.println("generating processDressmakerList...");
        if (editable) {
            employee = (Employee) getSession().getAttribute("employee");
            if (id == null) {
                processDressmakers = processDressmakerManager.findByEmployeePay(employee);
            } else {
                PaymentsPant pC = paymentsPantManager.get(id);
                processDressmakers = new ArrayList<ProcessDressmaker>();
                for (AsignationPantPay aCP : pC.getAsignationPantPays()) {
                    ProcessDressmaker cP = new ProcessDressmaker(aCP.getProcessDressmaker().getId(), aCP.getProcessDressmaker().getInitDate(), aCP.getProcessDressmaker().getTotalAmount(), aCP.getProcessDressmaker().getTotalAmountFail(), aCP.getProcessDressmaker().getTotalCurrentAmount(), aCP.getProcessDressmaker().getEndDate());
                    cP.setTotalCurrentAmount(cP.getTotalCurrentAmount() + aCP.getAmountPayed());
                    processDressmakers.add(cP);
                }
                List<ProcessDressmaker> processDressmakerList = processDressmakerManager.findByEmployeePay(employee);
                if (processDressmakerList.size() > 0 && processDressmakerList.get(0).getId().equals(processDressmakers.get(processDressmakers.size() - 1).getId())) {
                    processDressmakerList.remove(0);
                }
                processDressmakers.addAll(processDressmakerList);
            }
        } else {
            PaymentsPant pC = paymentsPantManager.get(id);
            processDressmakers = new ArrayList<ProcessDressmaker>();
            for (AsignationPantPay aCP : pC.getAsignationPantPays()) {
                processDressmakers.add(aCP.getProcessDressmaker());
            }
        }

        return SUCCESS;
    }

    public String delete() {
        System.out.println("deleting PaymentsPant...");
        if(id != null){
            paymentsPant = paymentsPantManager.get(id);
            List<AsignationPantPay> asignationPantPays = asignationPantPayManager.findByPaymentsPant(paymentsPant);
            for (AsignationPantPay a : asignationPantPays) {
                a.getProcessDressmaker().setTotalCurrentAmount(a.getProcessDressmaker().getTotalCurrentAmount() + a.getAmountPayed());
                processDressmakerManager.save(a.getProcessDressmaker());
            }

            periodPaymentEmployee = paymentsPant.getPeriodPaymentEmployee();
            periodPaymentEmployee.setCurrentAmount(periodPaymentEmployee.getCurrentAmount() + paymentsPant.getAmount());
            periodPaymentEmployee.setAmountPayment(periodPaymentEmployee.getAmountPayment() - paymentsPant.getAmount());
            periodPaymentEmployeeManager.save(periodPaymentEmployee);
            
            paymentsPantManager.remove(paymentsPant.getId());
            saveMessage(getText("paymentsPant.deleted"));
        }
        
        return SUCCESS;
    }

    public String edit() {
        if (id != null) {
            paymentsPant = paymentsPantManager.get(id);
            employee = (Employee) getSession().getAttribute("employee");
            if (balanceEmployeeManager.lastBalance(employee).getId().equals(paymentsPant.getBalanceEmployee().getId())) {
                setEditable(true);
            }
        } else {
            paymentsPant = new PaymentsPant();
            setEditable(true);
        }

        return SUCCESS;
    }

    public String save() throws Exception {
        System.out.println("saving PaymentsPant...");

        availableAmount = getAvailableAmount();
        if(paymentsPant.getAmount() <= 0 || paymentsPant.getAmount() > availableAmount
           || paymentsPant.getCode() == null || paymentsPant.getCode().equals("")){
            errorMessage(getText("paymentsPant.amount")+" "+getText("errors.dynamicdoublerange")+" "+availableAmount+".");
            return INPUT;
        }

        boolean isNew = (paymentsPant.getId() == null);

        employee = (Employee) getSession().getAttribute("employee");
        employee = employeeManager.get(employee.getId());
        periodPaymentEmployee = periodPaymentEmployeeManager.getCurrentPeriodByIdEmployeeAndRole(employee.getId()
                                                     , employee.getRoleByName("ROLE_EMPLOYEE_DRESSMAKER").getIdRole());

        paymentsPant.setPeriodPaymentEmployee(periodPaymentEmployee);

        if (isNew) {
            paymentsPant = paymentsPantManager.save(paymentsPant);
            List<ProcessDressmaker> processDressmakerList = processDressmakerManager.findByEmployeePay(employee);
            Double cont = paymentsPant.getAmount();
            for (ProcessDressmaker cP : processDressmakerList) {
                AsignationPantPay a = new AsignationPantPay();
                a.setProcessDressmaker(cP);
                a.setPaymentsPant(paymentsPant);
                if (cP.getTotalCurrentAmount() < cont) {
                    a.setAmountPayed(cP.getTotalCurrentAmount());
                    asignationPantPayManager.save(a);
                    cont = cont - cP.getTotalCurrentAmount();
                    cP.setTotalCurrentAmount(0D);
                    processDressmakerManager.save(cP);
                } else {
                    a.setAmountPayed(cont);
                    asignationPantPayManager.save(a);
                    cP.setTotalCurrentAmount(cP.getTotalCurrentAmount() - cont);
                    processDressmakerManager.save(cP);
                    break;
                }
            }
            BalanceEmployee bE = new BalanceEmployee();
            bE.setPeriodPaymentEmployee(periodPaymentEmployee);
            bE.setPaymentsPant(paymentsPant);
            bE.setAmountPaid(paymentsPant.getAmount());
            bE.setDateBalance(paymentsPant.getDatePay());
            bE.setObservation(observation);
            bE.setTypeBalance(3); // for payment normal
            bE.setBalance(periodPaymentEmployee.getCurrentAmount() - paymentsPant.getAmount());
            balanceEmployeeManager.save(bE);

            periodPaymentEmployee.setAmountPayment(periodPaymentEmployee.getAmountPayment() + paymentsPant.getAmount());
            periodPaymentEmployee.setCurrentAmount(periodPaymentEmployee.getCurrentAmount() - paymentsPant.getAmount());
            periodPaymentEmployeeManager.save(periodPaymentEmployee);

    }

        String key = (isNew) ? "paymentsPant.added" : "paymentsPant.updated";
        saveMessage(getText(key));

        return SUCCESS;
    }

    public String back() {
        getSession().removeAttribute("employee");
        return SUCCESS;
    }

    public void setPaymentsPantManager(PaymentsPantManager paymentsPantManager) {
        this.paymentsPantManager = paymentsPantManager;
    }

    public void setAsignationPantPayManager(AsignationPantPayManager asignationPantPayManager) {
        this.asignationPantPayManager = asignationPantPayManager;
    }

    public void setEmployeeManager(EmployeeManager employeeManager) {
        this.employeeManager = employeeManager;
    }

    public void setProcessDressmakerManager(ProcessDressmakerManager processDressmakerManager) {
        this.processDressmakerManager = processDressmakerManager;
    }

    public void setBalanceEmployeeManager(BalanceEmployeeManager balanceEmployeeManager) {
        this.balanceEmployeeManager = balanceEmployeeManager;
    }

    public List<PaymentsPant> getPaymentsPants() {
        return paymentsPants;
    }

    public List<BalanceEmployee> getBalances() {
        return balances;
    }

    public String list() {
        if (idEmployee != null) {
            employee = employeeManager.get(idEmployee);
            getSession().setAttribute("employee", getEmployee());
        } else {
            employee = (Employee) getSession().getAttribute("employee");
        }

        if (employee != null) {
            periodPaymentEmployee = periodPaymentEmployeeManager.getCurrentPeriodByIdEmployeeAndRole(employee.getId()
                                                               , employee.getRoleByName("ROLE_EMPLOYEE_DRESSMAKER").getIdRole());
            balances = periodPaymentEmployee.getBalanceEmployess();
            if(!balances.isEmpty()){
                lastBalanceId = balances.get(balances.size()-1).getId();
            } else {
                lastBalanceId = 0l;
            }
            List<ProcessDressmaker> cPs = processDressmakerManager.findByEmployeePay(employee);
            if (cPs != null && cPs.size() > 0) {
                canAdd = true;
            }
            return SUCCESS;
        } else {
            System.out.println("employee is null: idEmployee = " + idEmployee);
            return ERROR;
        }
    }

    public String help() {
        return SUCCESS;
    }

    public String helpList() {
        return SUCCESS;
    }

    public PeriodPaymentEmployee getPeriodPaymentEmployee() {
        return periodPaymentEmployee;
    }

    public void setPeriodPaymentEmployee(PeriodPaymentEmployee periodPaymentEmployee) {
        this.periodPaymentEmployee = periodPaymentEmployee;
    }

    public PeriodPaymentEmployeeManager getPeriodPaymentEmployeeManager() {
        return periodPaymentEmployeeManager;
    }

    public void setPeriodPaymentEmployeeManager(PeriodPaymentEmployeeManager periodPaymentEmployeeManager) {
        this.periodPaymentEmployeeManager = periodPaymentEmployeeManager;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setIdEmployee(Long idEmployee) {
        this.idEmployee = idEmployee;
    }

    public PaymentsPant getPaymentsPant() {
        return paymentsPant;
    }

    public void setPaymentsPant(PaymentsPant paymentsPant) {
        this.paymentsPant = paymentsPant;
    }

    public Employee getEmployee() {
        return employee;
    }

    public boolean isEditable() {
        return editable;
    }

    public void setEditable(boolean editable) {
        this.editable = editable;
    }

    public Long getLastBalanceId() {
        return lastBalanceId;
    }

    public boolean isCanAdd() {
        return canAdd;
    }

    public List<ProcessDressmaker> getProcessDressmakers() {
        return processDressmakers;
    }

    public String getObservation() {
        return observation;
    }

    public void setObservation(String observation) {
        this.observation = observation;
    }

}
